package com.wtwd.campus.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wtwd.campus.common.Constants;
import com.wtwd.campus.common.RespCode;
import com.wtwd.campus.common.RespEntity;
import com.wtwd.campus.dao.CustomerMapper;
import com.wtwd.campus.dao.DeviceInfoMapper;
import com.wtwd.campus.entity.*;
import com.wtwd.campus.model.vo.ResultVO;
import com.wtwd.campus.service.CustomerService;
import com.wtwd.campus.utils.AppKeySecretUtils;
import com.wtwd.campus.utils.DateUtils;
import com.wtwd.campus.utils.Tools;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.stream.Collectors;

/**
 * @Author ldaoliang
 * @Date create in 9:10 2021/6/22
 * @Description
 */
@Service
public class CustomerServiceImpl implements CustomerService {

    @Resource
    private CustomerMapper customerMapper;
    @Resource
    private DeviceInfoMapper deviceInfoMapper;

    @Override
    public SysCustomer getSysCustomerByAppKey(String appKey) {
        return customerMapper.getCustomerInfoByAppKey(appKey);
    }

    @Override
    public int updateCustomerPushUrl(Integer customerId, String pushUrl, Integer status) {
        return customerMapper.updatePushUrl(customerId, pushUrl, status);
    }

    @Override
    public SysCustomer getSysCustomerById(Integer customerId) {
        return customerMapper.getCustomerInfoById(customerId);
    }

    @Override
    public int saveFailedPush(Integer customerId, String imei, String data) {
        return customerMapper.saveFailedPushData(customerId, imei, data);
    }

    @Override
    public List<WhiteCallVo> getDeviceWhiteCallList(String imei) {
        List<WhiteCallVo> whiteCall = customerMapper.getDeviceWhiteCallList(imei);
        for (WhiteCallVo callVo : whiteCall) {
            if (callVo.getSequence() > 3 && callVo.getSequence() < 7) {
                callVo.setSequence(callVo.getSequence() - 3);
            }
        }
        return whiteCall;
    }

    @Override
    public RespCode verifyWhiteCallSequenceOperation(Integer deviceId, Integer sequence, Integer operation) {
        DeviceWhiteCall deviceWhiteCall = customerMapper.getDeviceWhiteCallByDeviceIdAndSequence(deviceId, sequence);
        RespCode respCode = RespCode.SUCCESS;
        if (operation.intValue() == Constants.OPERATOR_ADD) {
            if (deviceWhiteCall != null) {
                respCode = RespCode.SEQUENCE_EXIST_DATA;
            }
        } else if (operation.intValue() == Constants.OPERATOR_DEL || operation.intValue() == Constants.OPERATOR_UPDATE) {
            if (deviceWhiteCall == null) {
                respCode = RespCode.SEQUENCE_NOT_EXIST_DATA;
            }
        } else {
            respCode = RespCode.ILLEGAL_OPERATION;
        }
        return respCode;
    }

    @Override
    public List<ClassPatternVo> getDeviceClassPatternList(String imei) {
        return customerMapper.getDeviceClassPatternList(imei);
    }

    @Override
    public RespCode verifyClassPatternSequenceOperation(Integer deviceId, Integer sequence, Integer operation) {
        ClassPatternVo classPatternVo = customerMapper.getClassPatternByDeviceIdAndSequence(deviceId, sequence);
        RespCode respCode = RespCode.SUCCESS;
        if (operation.intValue() == Constants.OPERATOR_ADD) {
            if (classPatternVo != null) {
                respCode = RespCode.SEQUENCE_EXIST_DATA;
            }
        } else if (operation.intValue() == Constants.OPERATOR_DEL || operation.intValue() == Constants.OPERATOR_UPDATE) {
            if (classPatternVo == null) {
                respCode = RespCode.SEQUENCE_NOT_EXIST_DATA;
            }
        } else {
            respCode = RespCode.ILLEGAL_OPERATION;
        }
        return respCode;
    }

    @Override
    public IPage<SysCustomer> getSysCustomerList(Page<SysCustomer> page, String customerName) {
        return customerMapper.getSysCustomerList(page, customerName);
    }

    @Override
    public ResultVO addCustomer(String customerName) {
        // 校验名字是否重复
        SysCustomer sysCustomer = customerMapper.getSysCustomerByName(customerName);
        if (sysCustomer != null) {
            return ResultVO.error(RespCode.CUSTOMER_EXIST);
        }
        // 生成appKey appSecret
        String appKey = AppKeySecretUtils.getAppKey();
        String appSecret = AppKeySecretUtils.getAppSecret();
        int i = customerMapper.addSysCustomer(customerName, appKey, appSecret, System.currentTimeMillis());
        return i > 0 ? ResultVO.ok() : ResultVO.error(RespCode.FAILED);
    }

    @Override
    public ResultVO updateCustomer(Integer customerId, String customerName) {
        // 校验名字是否重复
        SysCustomer sysCustomer = customerMapper.getSysCustomerByName(customerName);
        if (sysCustomer != null) {
            return ResultVO.error(RespCode.CUSTOMER_EXIST);
        }
        int i = customerMapper.updateCustomer(customerId, customerName);
        return i > 0 ? ResultVO.ok() : ResultVO.error(RespCode.FAILED);
    }

    @Override
    public ResultVO startDisableCustomer(Integer customerId, Integer onOff) {
        int i = customerMapper.startDisableCustomer(customerId, onOff);
        return i > 0 ? ResultVO.ok() : ResultVO.error(RespCode.FAILED);
    }

//    @Override
//    public int savePushData(PushData pushData) {
//        String imei = pushData.getImei();
//        int dataType = pushData.getDataType();
//        int messageType = pushData.getMessageType();
//        String commandNumber = pushData.getCommandNumber();
//        String jsonString = JSONObject.toJSONString(pushData);
//        String time = DateUtils.format(new Date(pushData.getPushTime()), DateUtils.dateFormat4);
//        int i = customerMapper.savePushData(imei, messageType, dataType, commandNumber, jsonString, time);
//        return i;
//    }

    @Override
    public List<Map<String, Object>> getPushRecord(String imei) {
        return customerMapper.getPushRecord(imei);
    }

    @Override
    public RespCode addOrUpdateFence(JSONObject jsonObject, Integer customerId, int type) {
        String fenceName = jsonObject.getString("fenceName");
        Integer radius = jsonObject.getInteger("radius");
        Integer fenceType = jsonObject.getInteger("fenceType");
        String longitude = jsonObject.getString("longitude");
        String latitude = jsonObject.getString("latitude");
        String timePeriod = jsonObject.getString("timePeriod");
        String imei = jsonObject.getString("imei");
        // 校验参数
        if (Tools.stringIsBlank(fenceName, longitude, latitude, imei, timePeriod) || radius == null || fenceType == null) {
            return RespCode.PARAMETERIS_MiSSING;
        }
        JSONArray jsonArray = null;
        try {
            jsonArray = JSONArray.parseArray(timePeriod);
            jsonArray.toJavaList(CustomerFencePeriod.class);
        } catch (Exception e) {
            return RespCode.TIME_PERIOD_FIELD_MISSING;
        }
        // 校验数组(最多设置三组数据)
        if (jsonArray.size() > 3) {
            return RespCode.TIME_PERIOD_TOO_MUCH;
        }

        DeviceInfo deviceInfo = deviceInfoMapper.getDeviceInfoByImei(imei);
        if (deviceInfo == null) {
            return RespCode.DEVICE_NOT_FOUND;
        }
        if (!customerId.equals(deviceInfo.getCustomerId())) {
            return RespCode.CAN_NOT_OPERATION_DEVICE;
        }
        // 添加
        if (type == 1) {
            CustomerFence customerFence = new CustomerFence();
            customerFence.setCustomerId(customerId);
            customerFence.setCreateTime(System.currentTimeMillis());
            customerFence.setFenceName(fenceName);
            customerFence.setFenceType(fenceType);
            customerFence.setTimePeriod(timePeriod);
            customerFence.setLastUpdateTime(System.currentTimeMillis());
            customerFence.setRadius(radius);
            customerFence.setImei(imei);
            customerFence.setLatitude(latitude);
            customerFence.setLongitude(longitude);
            int i = customerMapper.addCustomerFence(customerFence);
            return i > 0 ? RespCode.SUCCESS : RespCode.FAILED;
        } else {
            Integer fenceId = jsonObject.getInteger("fenceId");
            CustomerFence customerFence = customerMapper.getCustomerFenceById(fenceId);
            if (customerFence == null) {
                return RespCode.FENCE_NOT_FOUND;
            }
            customerFence.setId(fenceId);
            customerFence.setFenceName(fenceName);
            customerFence.setFenceType(fenceType);
            customerFence.setTimePeriod(timePeriod);
            customerFence.setLastUpdateTime(System.currentTimeMillis());
            customerFence.setRadius(radius);
            customerFence.setLatitude(latitude);
            customerFence.setLongitude(longitude);
            int i = customerMapper.updateCustomerFence(customerFence);
            return i > 0 ? RespCode.SUCCESS : RespCode.FAILED;
        }
    }

    @Override
    public RespCode delFence(JSONObject jsonObject, Integer customerId) {
        Integer fenceId = jsonObject.getInteger("fenceId");
        CustomerFence customerFence = customerMapper.getCustomerFenceById(fenceId);
        if (customerFence == null) {
            return RespCode.FENCE_NOT_FOUND;
        }
        if (!customerId.equals(customerFence.getCustomerId())) {
            return RespCode.CAN_NOT_OPERATION_DEVICE;
        }
        int i = customerMapper.delCustomerFence(fenceId);
        return i > 0 ? RespCode.SUCCESS : RespCode.FAILED;
    }

    @Override
    public List<JSONObject> getDeviceFenceList(String imei) {
        List<CustomerFence> customerFenceList = customerMapper.getDeviceFenceList(imei);
        List<JSONObject> jsonObjectList = new ArrayList<>();
        if (customerFenceList != null) {
            for (CustomerFence fence : customerFenceList) {
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("fenceId", fence.getId());
                jsonObject.put("fenceName", fence.getFenceName());
                jsonObject.put("radius", fence.getRadius());
                jsonObject.put("fenceType", fence.getFenceType());
                jsonObject.put("longitude", fence.getLongitude());
                jsonObject.put("latitude", fence.getLatitude());
                jsonObject.put("createTime", fence.getCreateTime());
                jsonObject.put("lastUpdateTime", fence.getLastUpdateTime());
                jsonObject.put("timePeriod", JSONArray.parseArray(fence.getTimePeriod(), CustomerFencePeriod.class));
                jsonObjectList.add(jsonObject);
            }
        }
        return jsonObjectList;
    }

    @Override
    public RespEntity bindingStudent(String imei, String stuName) {
        DeviceInfo deviceInfo = deviceInfoMapper.getDeviceInfoByImei(imei);
        if (deviceInfo != null) {
            if (StringUtils.isBlank(deviceInfo.getCusStuName())) {
                int i = customerMapper.bindCusStudent(imei, stuName);
                return new RespEntity(i > 0 ? RespCode.SUCCESS : RespCode.FAILED);
            } else {
                return new RespEntity(RespCode.DEVICE_BINDED);
            }
        }
        return new RespEntity(RespCode.DEVICE_NOT_FOUND);
    }

    @Override
    public DeviceWhiteCall getDeviceWhiteCallByDeviceIdAndSequence(Integer deviceId, Integer sequence) {
        return customerMapper.getDeviceWhiteCallByDeviceIdAndSequence(deviceId, sequence);
    }

    @Override
    public List<DeviceSOSList> getDeviceSosPhoneList(Integer deviceId) {
        return customerMapper.getDeviceSosPhoneList(deviceId);
    }

    @Override
    public int updateSosPhoneStatus(Integer deviceId, Integer sequence, Integer status, String commandNumber) {
        return customerMapper.updateSosPhoneStatus(deviceId, status, sequence, commandNumber);
    }

    @Override
    public int addSosPhone(Integer deviceId, Integer sequence, String name, String phone, Integer status, String commandNumber) {
        return customerMapper.addSosPhone(deviceId, sequence, name, phone, status, commandNumber);
    }
}
